<?php

declare(strict_types=1);

namespace app\sys\controller;

use app\sys\service\SystemMenuService;
use think\admin\Controller;
use think\admin\model\SysMenu;
use think\admin\model\SysModule;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 菜单接口
 * Class Menu
 * @package app\sys\controller
 */
class Menu extends Controller
{
    /**
     * 获取模块选择器
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function moduleSelector()
    {
        $modules = SysModule::mk()
            ->where(['is_deleted' => 0, 'status' => 0])
            ->order('sort asc,id asc')
            ->select()
            ->toArray();
        $this->success('数据获取成功', $modules);
    }

    /**
     * 菜单所属模块更改
     * @auth true
     * @return void
     */
    public function changeModule()
    {
        sysoplog('菜单管理', '菜单所属模块更改成功');
        SysMenu::mForm('form');
    }

    /**
     * 获取菜单选择树
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function menuTreeSelector()
    {
        $menus = SysMenu::mk()
            ->where(['is_deleted' => 0, 'status' => 0])
            ->where(['category' => 'MENU'])
            ->order('module asc')
            ->field('*,parent_id as parentId')
            ->select()
            ->toArray();
        foreach ($menus as &$v) {
            $v['title'] = $v['title'] . '[' . $v['module'] . ']';
        }
        $lists = SystemMenuService::instance()->toTree($menus);
        $this->success('数据获取成功', $lists);
    }

    /**
     * 获取菜单树
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function tree()
    {
        $query = SysMenu::mQuery();
        $query->where(['is_deleted' => 0]);

        // 数据列表搜索过滤
        $query->equal('module,parent_id,status')->dateBetween('create_time');
        $query->like('title,code,package');
        $query->dataScope('created_by');
        $lists = $query->order('sort ASC,id ASC')->page(false, false);
        $menu = [];
        foreach ($lists['list'] as $v) {
            if ($v['category'] != 'BUTTON') {
                $menu[] = $v;
            }
        }
        $menusTree = SystemMenuService::instance()->toTree($menu);
        sysoplog('菜单管理', '菜单树获取成功');
        $this->success('数据获取成功', $menusTree);
    }

    /**
     * 获取一条菜单详情
     * @auth true
     * @return void
     */
    public function detail()
    {
        sysoplog('菜单管理', '菜单获取成功');
        $this->success('操作成功', SysMenu::detail($this->request->param('id')));
    }

    /**
     * 添加菜单
     * @auth true
     * @return void
     */
    public function add()
    {
        sysoplog('菜单管理', '菜单保存成功');
        SysMenu::mForm('form');
    }

    /**
     * 更新菜单
     * @auth true
     * @return void
     */
    public function edit()
    {
        sysoplog('菜单管理', '菜单更新成功');
        SysMenu::mForm('form');
    }

    /**
     * 修改菜单状态
     * @auth true
     * @return void
     */
    public function state()
    {
        sysoplog('菜单管理', '菜单状态更新成功');
        SysMenu::mSave($this->_vali([
            'status.in:0,1' => '状态值范围异常！',
            'status.require' => '状态值不能为空！',
        ]));
    }

    /**
     * 移到回收站
     * @auth true
     * @return void
     */
    public function delete()
    {
        $id = intval($this->request->param('id'));
        if ($this->_checkChildrenExists($id)) {
            $this->error('存在下级菜单，请先删除下级菜单后再删除该菜单。');
        } else {
            sysoplog('菜单管理', '菜单删除成功');
            SysMenu::mSave(['is_deleted' => 1]);
        }
    }

    /**
     * 检查子菜单是否存在
     * @param int $id
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function _checkChildrenExists(int $id): bool
    {
        if (SysMenu::mk()->whereIn('parent_id', $id)->where(['is_deleted' => 0])->find()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 重写菜单数据
     * @auth true
     */
    public function reset()
    {
        $this->_queue('重写菜单数据', "xadmin:sysmenu");
    }

}